package zsc.ruanc.practicaltraining.service.Impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;
import zsc.ruanc.practicaltraining.exception.ApiException;
import zsc.ruanc.practicaltraining.mapper.ArticleMapper;
import zsc.ruanc.practicaltraining.mapper.AuthorityMapper;
import zsc.ruanc.practicaltraining.mapper.Redis;
import zsc.ruanc.practicaltraining.mapper.UserMapper;
import zsc.ruanc.practicaltraining.model.domain.TUser;
import zsc.ruanc.practicaltraining.model.vo.SelectConditionVo;
import zsc.ruanc.practicaltraining.model.vo.UserVo;
import zsc.ruanc.practicaltraining.model.vo.createUserVo;
import zsc.ruanc.practicaltraining.service.UserService;
import zsc.ruanc.practicaltraining.utils.TokenUtils;
import zsc.ruanc.practicaltraining.utils.UploadUtils;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
public class UserServiceImpl implements UserService {

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private Redis redis;

    @Autowired
    private AuthorityMapper authorityMapper;

    @Autowired
    private ArticleMapper articleMapper;

    @Value("${cbs.imagesPath.file}")
    private String resPath;


    /**
     * 创建用户
     * @param createUserVo
     * @return 返回用户id
     */
    @Override
    @Transactional
    public int createUser(createUserVo createUserVo) {
        if (userMapper.checkUsername(createUserVo.getUsername())) {
            throw new ApiException(-4);
        }
        TUser user = new TUser(createUserVo);
        userMapper.insertUser(user);
        // 该url是对外暴露的接口
        userMapper.updatePhoto(user.getId(), "/res/" + String.valueOf(user.getId()) + "/user.jpg");


        // 给用户一张初始的头像图片
        new Thread(new Runnable() {
            @Override
            public void run() {
                String rootPath = resPath + String.valueOf(user.getId()) + "/";
                try {
                    File dir = new File(rootPath);
                    if (!dir.exists()) {
                        dir.mkdirs();
                    }
                    File fromImg = new File(resPath + "user.jpg");
                    File toImg = new File(rootPath + "user.jpg");
                    Files.copy(fromImg.toPath(), toImg.toPath());
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }).start();


        return user.getId();
    }

    /**
     * 找回密码
     * @param email
     * @param password
     * @return
     */
    @Override
    @Transactional
    public boolean updatePassword(String email, String password) {
        int x = userMapper.updatePassword(email, password);
        if (x == 0) {
            throw new ApiException(404, "未找到数据");
        }
        return true;
    }

    /**
     * 修改密码
     * @param id
     * @param oldPassword
     * @param newPassword
     * @return
     */
    @Override
    @Transactional
    public boolean updatePassword(int id, String oldPassword, String newPassword) {
        TUser user = userMapper.selectById(id);
        if (!oldPassword.equals(user.getPassword())) {
            throw new ApiException(-8, "原密码输入错误!!!");
        }
        if (oldPassword.equals(newPassword)) {
            throw new ApiException(400, "新密码与原密码一致");
        }
        userMapper.updatePassword2(id, newPassword);
        redis.delete(String.valueOf(id));
        return true;
    }

    /**
     * 登录
     * @param email
     * @param password
     * @return
     */
    @Override
    @Transactional
    public String login(String email, String password) {
        TUser user = userMapper.login(email, password);
        if (user == null) {
            throw new ApiException(-8);
        }
        if (user.getValid() == false) {
            throw new ApiException(-8, "账号已被封锁");
        }

        // 查询用户身份
        String s = authorityMapper.selectRole(user.getRoleId());
        String key = TokenUtils.randomKey();
        // 存入redis 用户id为key， 密匙为value 一小时有效
        redis.set(String.valueOf(user.getId()), key, 3600);
        // 生成token
        String token = TokenUtils.create(user.getId(), s, user.getUsername(),  key);
        return token;
    }

    /**
     * 刷新token
     * @param id
     * @return
     */
    @Override
    public String refreshToken(int id) {
        TUser user = userMapper.selectById(id); // 获得用户
        if (user == null) {
            throw new ApiException(-8);
        }
        if (user.getValid() == false) {
            throw new ApiException(-8, "账号已被封锁");
        }
        // 查询用户身份
        String s = authorityMapper.selectRole(user.getRoleId());
        String key = TokenUtils.randomKey();
        // 存入redis 用户id为key， 密匙为value 一小时有效
        redis.set(String.valueOf(user.getId()), key, 3600);
        // 生成token
        String token = TokenUtils.create(user.getId(), s, user.getUsername(), key);
        return token;
    }

    /**
     * 退出登录
     * @param id
     * @return
     */
    @Override
    public boolean logout(int id) {
        redis.delete(String.valueOf(id));
        return true;
    }

    /**
     * 修改用户名
     * @param id
     * @param name
     * @return
     */
    @Override
    public boolean updateName(int id, String name) {
        if(userMapper.checkUsername(name)) {
            throw new ApiException(-4);
        }
        userMapper.updateUsername(id, name);
        return true;
    }

    /**
     * 修改邮箱
     * @param email
     * @return
     */
    @Override
    public boolean updateEmail(int id, String email) {
        userMapper.updateEmail(id, email);
        return true;
    }

    /**
     * 修改头像
     * @param file
     * @return
     */
    @Override
    public boolean updateHead(int id, MultipartFile file) {
        UploadUtils.save(file, resPath + String.valueOf(id) + "/", "user.jpg", true);
        return true;
    }

    /**
     * 修改一些无关紧要的信息 性别、生日。。。
     * @param userVo
     * @return
     */
    @Override
    public boolean updateInfo(UserVo userVo) {
        userMapper.updateUserInfo(userVo);
        return true;
    }

    /**
     * 获得用户信息
     * @param id
     * @return
     */
    @Override
    public TUser getUser(int id) {
        TUser user = userMapper.selectById(id);
        user.setPassword(""); // 不返回密码
        return user;
    }

    /**
     * 一个用户查询另一个用户
     * @param username
     * @return
     */
    @Override
    public TUser getUserInfo(String username) {
        TUser user = userMapper.selectByName(username);
        if (user == null) {
            throw new ApiException(-5);
        }
        if (user.getValid() == false) {
            throw new ApiException(-11, "该账号存在违规行为已被封号");
        }
        user.setArticleCount(articleMapper.getCount(user.getId(), true)); // 查询该用户的文章数
        // 去除敏感信息
        user.setRoleId(null);
        user.setPassword("");
        user.setEmail("");
        return user;
    }

    //------------管理员权限-------------------------------------

    /**
     * 按条件查询用户
     * @param id
     * @param email
     * @return
     */
    @Override
    public TUser select(Integer id, String email) {
        if (id != null) {
            return userMapper.selectById(id);
        } else if (email != null) {
            return userMapper.selectByEmail(email);
        }
        return null;
    }

    /**
     * 分页查询
     * @param cur
     * @param size
     * @return
     */
    @Override
    public Map selectPage(int cur, int size, String text) {
        PageHelper.startPage(cur, size).setOrderBy("id asc");
        PageInfo<TUser> userPageInfo = new PageInfo<>(this.userMapper.selectPage(text));
        Map<String, Object> map = new HashMap();
        map.put("total", userPageInfo.getTotal());
        map.put("list", userPageInfo.getList());
        return map;
    }

    /**
     * 封号激活
     * @param id
     * @param flag
     * @return
     */
    @Override
    public boolean setValid(int id, boolean flag) {
        userMapper.updateValid(id, flag);
        return true;
    }

    /**
     *  把用户升级成管理员或者降为普通用户
     * @param userId 目标id
     * @param role  1:管理员 2：普通用户
     * @return
     */
    @Override
    public boolean updateRole(int userId, int role) {
        int x = userMapper.updateRole(userId, role);

        if (x == 0) {
            throw new ApiException(404, "未找到用户");
        }
        return true;
    }


}
